package top.sdwu_top.kbase.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import top.sdwu_top.kbase.common.aspect.exception.MyException;
import top.sdwu_top.kbase.dto.KbaseKnowledgeTagDto;
import top.sdwu_top.kbase.entity.KbaseAuthOrg;
import top.sdwu_top.kbase.entity.KbaseAuthRole;
import top.sdwu_top.kbase.entity.KbaseAuthUser;
import top.sdwu_top.kbase.entity.KbaseKnowledgeTag;
import top.sdwu_top.kbase.mapper.KbaseAuthOrgMapper;
import top.sdwu_top.kbase.service.IKbaseAuthOrgService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import top.sdwu_top.kbase.service.IKbaseAuthUserService;
import top.sdwu_top.kbase.vo.KbaseAuthOrgVo;
import top.sdwu_top.kbase.vo.KbaseAuthRoleVo;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 组织表 服务实现类
 * </p>
 *
 * @author zhipeng.duan@nvr-china.com
 * @since 2020-02-20
 */
@Slf4j
@Service
public class KbaseAuthOrgServiceImpl extends ServiceImpl<KbaseAuthOrgMapper, KbaseAuthOrg> implements IKbaseAuthOrgService {

    @Autowired
    IKbaseAuthUserService userService;


    @Override
    public boolean save(KbaseAuthUser user, KbaseAuthOrg authOrg) {
        log.info("用户子组织:{}",getSubOrgIdList(user));
        if (Objects.isNull(authOrg) || StringUtils.isBlank(authOrg.getOrgName())) {
            throw new MyException(50003, "校验失败，组织名不能为空");
        }
        if (exist(authOrg)) {
            throw new MyException(50003, "组织名已存在");
        }
        return super.save(authOrg);
    }

    @Override
    public boolean update(KbaseAuthUser user, KbaseAuthOrg authOrg) {
        if (Objects.isNull(authOrg) || StringUtils.isBlank(authOrg.getOrgName())) {
            throw new MyException(50003, "校验失败，组织名不能为空");
        }
        if (exist(authOrg)) {
            throw new MyException(50003, "组织名已存在");
        }
        return super.updateById(authOrg);
    }

    @Override
    public boolean delete(KbaseAuthUser user, String id) {
        if (hasChild(id)) {
            throw new MyException(50003, "不能删除含有子组织的组织");
        }
        return super.removeById(id);
    }

    @Override
    public KbaseAuthOrg getChain(KbaseAuthUser user, String id) {
        if (!this.userCanOperate(user, id)) {
            throw new MyException(50003, "当前用户无权操作这个组织");
        }
        KbaseAuthOrg authOrg = super.getById(id);
        if (Objects.isNull(authOrg)) {
            return new KbaseAuthOrg();
        }
        List<KbaseAuthOrg> nowList = Lists.newArrayList(authOrg);
        while(CollectionUtils.isNotEmpty(nowList)) {
            List<KbaseAuthOrg> tempList = Lists.newArrayList();
            for (KbaseAuthOrg org : nowList) {
                List<KbaseAuthOrg> childList = getChildList(org.getId());
                org.setChildList(childList);
                tempList.addAll(childList);
            }
            nowList.clear();
            nowList.addAll(tempList);
            tempList.clear();
        }
        //父组织名称
        if (StringUtils.isNotBlank(authOrg.getParentId())) {
            KbaseAuthOrg org = super.getById(authOrg.getParentId());
            if (Objects.nonNull(org)) {
                authOrg.setParentOrgName(org.getOrgName());
            }
        }

        return authOrg;
    }

    private List<KbaseAuthOrg> getChildList(String id) {
        if (StringUtils.isBlank(id)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        QueryWrapper<KbaseAuthOrg> qw = Wrappers.query();
        qw.eq("PARENT_ID", id);
        List<KbaseAuthOrg> authOrgList = super.list(qw);
        if (CollectionUtils.isEmpty(authOrgList)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        return authOrgList;
    }

    @Override
    public Page<KbaseAuthOrg> page(KbaseAuthUser user, KbaseAuthOrgVo authOrgVo) {
        QueryWrapper<KbaseAuthOrg> qw = Wrappers.query();
        qw.like(StringUtils.isNotBlank(authOrgVo.getOrgName()), "ORG_NAME", authOrgVo.getOrgName())
                .eq(StringUtils.isNotBlank(authOrgVo.getState()), "STATE", authOrgVo.getState())
                .eq(StringUtils.isNotBlank(authOrgVo.getParentId()), "PARENT_ID", authOrgVo.getParentId());
        Page<KbaseAuthOrg> authOrgPage = super.page(authOrgVo.getPage(), qw);
        if (CollectionUtils.isNotEmpty(authOrgPage.getRecords())) {
            authOrgPage.getRecords().parallelStream().forEach(i->{
                i.setManager(userService.getManagerByOrgId(i.getId()));
            });
        }
        return authOrgPage;
    }

    @Override
    public List<KbaseAuthOrg> getTreeList(KbaseAuthUser user) {
        QueryWrapper<KbaseAuthOrg> qw = Wrappers.query();
        List<String> subOrgList = this.getSubOrgIdList(user);
        if (CollectionUtils.isEmpty(subOrgList)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        qw.isNull("PARENT_ID")
                .in("ID", subOrgList);
        List<KbaseAuthOrg> authOrgList = super.list(qw);
        if (CollectionUtils.isEmpty(authOrgList)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        authOrgList.parallelStream().forEach(i->{
            KbaseAuthOrg authOrg = this.getChain(user, i.getId());
            i.setChildList(authOrg.getChildList());
        });
        return authOrgList;
    }

    @Override
    public List<String> getSubOrgIdList(KbaseAuthUser user) {
        List<String> resultList = Lists.newArrayList(user.getOrgId());
        List<String> tempList = Lists.newArrayList(resultList);
        while(CollectionUtils.isNotEmpty(tempList)) {
            List<String> subOrgIdList = this.list(tempList);
            resultList.addAll(subOrgIdList);
            tempList.clear();
            tempList.addAll(subOrgIdList);
        }
        return resultList;
    }

    private  List<String> list(List<String> orgIdList) {
        QueryWrapper<KbaseAuthOrg> qw = Wrappers.query();
        qw.in("PARENT_ID", orgIdList);
        List<KbaseAuthOrg> authOrgList = super.list(qw);
        if (CollectionUtils.isEmpty(authOrgList)) {
            return Lists.newArrayListWithExpectedSize(0);
        }
        return authOrgList.parallelStream().map(KbaseAuthOrg::getId).collect(Collectors.toList());
    }

    private boolean exist(KbaseAuthOrg authOrg) {
        QueryWrapper<KbaseAuthOrg> qw = Wrappers.query();
        qw.eq("ORG_NAME", authOrg.getOrgName());
        qw.last("limit 1");
        return Objects.nonNull(super.getOne(qw));
    }

    private boolean hasChild(String parentId) {
        if (StringUtils.isBlank(parentId)) {
            return false;
        }
        QueryWrapper<KbaseAuthOrg> qw = Wrappers.query();
        qw.eq("PARENT_ID", parentId);
        qw.last("limit 1");
        return Objects.nonNull(super.getOne(qw));
    }

    public boolean userCanOperate(KbaseAuthUser user, String orgId) {
        if (Objects.equals(user.getOrgId(), orgId)) {
            return true;
        }
        List<String> resultList = Lists.newArrayList(user.getOrgId());
        List<String> tempList = Lists.newArrayList(resultList);
        while(CollectionUtils.isNotEmpty(tempList)) {
            List<String> subOrgIdList = this.list(tempList);
            for (String s : subOrgIdList) {
                if (Objects.equals(s, orgId)) {
                    return true;
                }
            }
            resultList.addAll(subOrgIdList);
            tempList.clear();
            tempList.addAll(subOrgIdList);
        }
        return false;
    }

}
